#ifndef BLOCKOPERATION_H
#define	BLOCKOPERATION_H

/// The function MoveRight checks if the block can move or is stuck.
/**
 * The function MoveRight checks if the block, based on the type of
 * the block, can move to the right or is stuck.
 * Returns the new x position.
 * @param block contains all the information about the block
 */
int MoveRight(pivot block);

/// The function MoveLeft checks if the block can move or is stuck.
/**
 * The function MoveLeft checks if the block, based on the type of
 * the block, can move to the left or is stuck.
 * Returns the new x position.
 * @param block contains all the information about the block
 */
int MoveLeft(pivot block);

/// The function ControlLeftRightX checks if the block is at the edge of the screen.
/**
 * The function ControlLeftRightX checks if the block is at the edge,
 * left or right, of the screen.
 * Returns the max x position
 * @param pivot_x contains the x position of the block
 * @param actual_type is used for the type I, is the only block that go
 *        on the extreme right of the field
 */
int ControlLeftRightX(short int &pivot_x, block_type actual_type);

/// The function ControlY checks if the block is at the bottom of the screen.
/**
 * The function ControlY checks if the block is at the bottom of the screen.
 * Returns true if can move down.
 * @param pivot_y contains the y position of the block
 * @param shift_down contains the number of tiles that must be added to the
 *        pivot_y
 */
bool ControlY(short int pivot_y, int shift_down);

/// The function controls which fuction we have to use to rotate or move the block.
/**
 * The function controls which fuction we have to use to rotate or move the block and
 * call the corrected function.
 * Returns true if can move or rotate.
 * @param pivot_x contains the x position of the block
 * @param right stores the information about the direction of the movement
 *
 */
bool MoveLeftRight(pivot block, bool right);

/// Can the block I move or rotate?
/**
 * The function CanMoveRotateI checks if the block I can move or rotate.
 * Returns true if can move or rotate.
 * @param block contains the information of the block
 * @param move is true if the block is moving, false if the block is rotating
 * @param shift contains the value +/-1 if move is true, 0 if false
 */
bool CanMoveRotateI(pivot &block, bool move, short int shift);

/// Can the block J move or rotate?
/**
 * The function CanMoveRotateJ checks if the block J can move or rotate.
 * Returns true if can move or rotate.
 * @param block contains the information of the block
 * @param move is true if the block is moving, false if the block is rotating
 * @param shift contains the value +/-1 if move is true, 0 if false
 */
bool CanMoveRotateJ(pivot &block, bool move, short int shift);

/// Can the block L move or rotate?
/**
 * The function CanMoveRotateL checks if the block L can move or rotate.
 * Returns true if can move or rotate.
 * @param block contains the information of the block
 * @param move is true if the block is moving, false if the block is rotating
 * @param shift contain the value +/-1 if move is true, 0 if false
 */
bool CanMoveRotateL(pivot &block, bool move, short int shift);

/// Can the block O move?
/**
 * The function MoveLeftRightO checks if the block O can move.
 * Returns true if can move.
 * @param block contains the information of the block
 * @param shift contains the value +/-1
 */
bool MoveLeftRightO(pivot block, short int shift);

/// Can the block S move or rotate?
/**
 * The function CanMoveRotateS checks if the block S can move or rotate.
 * Returns true if can move or rotate.
 * @param block contains the information of the block
 * @param move if true the block is moving, false the block is rotating
 * @param shift contains the value +/-1 if move is true, 0 if false
 */
bool CanMoveRotateS(pivot &block, bool move, short int shift);

/// Can the block Z move or rotate?
/**
 * The function CanMoveRotateZ checks if the block Z can move or rotate.
 * Returns true if can move or rotate.
 * @param block contains the information of the block
 * @param move if true the block is moving, false the block is rotating
 * @param shift contains the value +/-1 if move is true, 0 if false
 */
bool CanMoveRotateZ(pivot &block, bool move, short int shift);

/// Can the block T move or rotate?
/**
 * The function CanMoveRotateT checks if the block T can move or rotate.
 * Returns true if can move or rotate.
 * @param block contains the information of the block
 * @param move if true the block is moving, false the block is rotating
 * @param shift contains the value +/-1 if move is true, 0 if false
 */
bool CanMoveRotateT(pivot &block, bool move, short int shift);

/// Draws the block I in the right position
/**
 * The function RotationI draws the block I based on the actual rotation.
 * @param block contains the information of the block
 */
void RotationI(pivot block);

/// Draws the block J in the right position
/**
 * The function RotationJ draws the block J based on the actual rotation.
 * @param block contains the information of the block
 */
void RotationJ(pivot block);

/// Draws the block L in the right position
/**
 * The function RotationL draws the block L based on the actual rotation.
 * @param block contains the information of the block
 */
void RotationL(pivot block);

/// Draws the block O in the right position
/**
 * The function RotationO draws the block O.
 * @param block contains the information of the block
 */
void RotationO(pivot block);

/// Draws the block S in the right position
/**
 * The function RotationS draws the block S based on the actual rotation.
 * @param block contains the information of the block
 */
void RotationS(pivot block);

/// Draws the block Z in the right position
/**
 * The function RotationZ draws the block Z based on the actual rotation.
 * @param block contains the information of the block
 */
void RotationZ(pivot block);

/// Draws the block T in the right position
/**
 * The function RotationT draws the block T based on the actual rotation.
 * @param block contains the information of the block
 */
void RotationT(pivot block);

///Can the block I move down?
/**
 * The function MoVeDownI checks if the block I, based on the actual rotation,
 * can move down.
 * Returns true if the block can move down, else if the block is stucked.
 * @param block contains the information of the block
 */
bool MoveDownI(pivot block);

///Can the block J move down?
/**
 * The function MoVeDownJ checks if the block J, based on the actual rotation,
 * can move down.
 * Returns true if the block can move down, else if the block is stucked.
 * @param block contains the information of the block
 */
bool MoveDownJ(pivot block);

///Can the block L move down?
/**
 * The function MoVeDownL checks if the block L, based on the actual rotation,
 * can move down.
 * Returns true if the block can move down, else if the block is stucked.
 * @param block contains the information of the block
 */
bool MoveDownL(pivot block);

///Can the block O move down?
/**
 * The function MoVeDownO checks if the block O can move down.
 * Returns true if the block can move down, else if the block is stucked.
 * @param block contains the information of the block
 */
bool MoveDownO(pivot block);

///Can the block S move down?
/**
 * The function MoVeDownS checks if the block S, based on the actual rotation,
 * can move down.
 * Returns true if the block can move down, else if the block is stucked.
 * @param block contains the information of the block
 */
bool MoveDownS(pivot block);

///Can the block Z move down?
/**
 * The function MoVeDownZ checks if the block Z, based on the actual rotation,
 * can move down.
 * Returns true if the block can move down, else if the block is stucked.
 * @param block contains the information of the block
 */
bool MoveDownZ(pivot block);

///Can the block T move down?
/**
 * The function MoVeDownT checks if the block T, based on the actual rotation,
 * can move down.
 * Returns true if the block can move down, else if the block is stucked.
 * @param block contains the information of the block
 */
bool MoveDownT(pivot block);

///The function blocks and saves the block I
/**
 * The function BlockI save thes block I, based on the actual rotation,
 * in the matrix field.
 * @param block contains the information of the block
 */
void BlockI(pivot block);

///The function blocks and saves the block J
/**
 * The function BlockJ saves the block J, based on the actual rotation,
 * in the matrix field.
 * @param block contains the information of the block
 */
void BlockJ(pivot block);

///The function blocks and saves the block L
/**
 * The function BlockL saves the block L, based on the actual rotation,
 * in the matrix field.
 * @param block contains the information of the block
 */
void BlockL(pivot block);

///The function blocks and saves the block O
/**
 * The function BlockO saves the block O in the matrix field.
 * @param block contains the information of the block
 */
void BlockO(pivot block);

///The function blocks and saves the block S
/**
 * The function BlockS saves the block S, based on the actual rotation,
 * in the matrix field.
 * @param block contains the information of the block
 */
void BlockS(pivot block);

///The function blocks and saves the block Z
/**
 * The function BlockZ saves the block Z, based on the actual rotation,
 * in the matrix field.
 * @param block contains the information of the block
 */
void BlockZ(pivot block);

///The function blocks and saves the block T
/**
 * The function BlockT saves the block T, based on the actual rotation,
 * in the matrix field.
 * @param block contains the information of the block
 */
void BlockT(pivot block);

#endif	/* BLOCKOPERATION_H */

